{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Transformers Agents kullanarak, tool-calling süper güçleriyle donatılmış bir ajan oluşturun 🦸 \n",
    "_Yazar: [Aymeric Roucher](https://huggingface.co/m-ric)_ _Çeviren: [Alper Erdoğan](https://github.com/alpererdogan8)_\n",
    "\n",
    "Bu notebook, harika **ajanlar** oluşturmak için [**Transformers Agents'ı**](https://huggingface.co/docs/transformers/en/agents) nasıl kullanabileceğinizi gösterir!\n",
    "\n",
    "**Ajanlar** nedir? Ajanlar, bir LLM tarafından desteklenen ve spesifik istemler ile çıktıların ayrıştırılması sayesinde belirli *araçları* kullanarak problemleri çözebilen sistemlerdir.\n",
    "\n",
    "Bu araçlar basitçe LLM'nin kendi başına iyi performans sergileyemediği işlevleri kapsar: örneğin [Llama-3-70B](https://huggingface.co/meta-llama/Meta-Llama-3-70B-Instruct) gibi metin üreten bir LLM için görüntü oluşturma aracı, web arama aracı veya hesap makinesi olabilir...\n",
    "\n",
    "**Transformers Agents** nedir? Kendi ajanlarınızı oluşturmak için yapı taşları sağlayan `transformers` kütüphanemizin bir uzantısıdır! [Dökümantasyondan](https://huggingface.co/docs/transformers/en/agents) daha fazla bilgi edinin.\n",
    "\n",
    "Nasıl kullanılacağına ve hangi kullanım senaryolarını çözebileceğine bakalım.\n",
    "\n",
    "Gerekli kütüphaneleri yüklemek için aşağıdaki satırı çalıştırın:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install \"transformers[agents]\" datasets langchain sentence-transformers faiss-cpu duckduckgo-search openai langchain-community --upgrade -q"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 🏞️ Çok Modlu + 🌐 Web tarayıcı asistanı\n",
    "\n",
    "Bu kullanım senaryosu için, internette gezinen ve görsel oluşturabilen bir ajan göstermek istiyoruz.\n",
    "\n",
    "Bunu oluşturmak için basitçe iki aracın hazır olması gerekiyor: görüntü oluşturma ve internet üzerinden arama.\n",
    "- Görsel oluşturmak için, Stable Diffusion kullanarak görseller oluşturmak üzere Hub'dan HF Inference API'yi (Serverless) kullanan bir araç yüklüyoruz.\n",
    "- İnternette arama yapmak için yerleşik bir araç kullanıyoruz."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from transformers import load_tool, ReactCodeAgent, HfApiEngine\n",
    "\n",
    "# Aracı Hub'dan içe aktarın\n",
    "image_generation_tool = load_tool(\"m-ric/text-to-image\", cache=False)\n",
    "\n",
    "# LangChain'den aracı içe aktarın\n",
    "from transformers.agents.search import DuckDuckGoSearchTool\n",
    "\n",
    "search_tool = DuckDuckGoSearchTool()\n",
    "\n",
    "llm_engine = HfApiEngine(\"Qwen/Qwen2.5-72B-Instruct\")\n",
    "# Ajanları her iki araçla başlatın.\n",
    "agent = ReactCodeAgent(\n",
    "    tools=[image_generation_tool, search_tool], llm_engine=llm_engine\n",
    ")\n",
    "\n",
    "# Çalıştır!\n",
    "result = agent.run(\n",
    "    \"Generate me a photo of the car that James bond drove in the latest movie.\",\n",
    ")\n",
    "result"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![Image of an Aston Martin DB5](https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/agents_db5.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 📚💬 RAG ile yinelemeli sorgu iyileştirme ve kaynak seçimi\n",
    "\n",
    "Kısa tanım: Retrieval-Augmented-Generation (RAG), ___“bir kullanıcı sorgusunu yanıtlamak için bir büyük dil modeli (LLM) kullanır, ancak yanıtı veri setinden elde edilen verilere dayandırır”___.\n",
    "\n",
    "Bu yöntemin yalın ya da fine-tuned bir LLM kullanımına göre birçok avantajı vardır: bunlardan birkaçını saymak gerekirse, cevabı doğru gerçeklere dayandırmaya ve karışıklıkları azaltmaya izin verir, LLM'e özgü bilgileri sağlamaya ve bilgi tabanından veriye erişimin ince taneli kontrolüne izin verir.\n",
    "\n",
    "- Şöyle bir senaryo düşünelim. RAG yöntemini uygulamak istiyoruz, ancak bazı parametrelerin dinamik olarak belirlenmesi gereken ek bir koşulumuz var. Örneğin, kullanıcı sorgusuna bağlı olarak aramayı bilgi tabanının belirli alt kümeleriyle sınırlamak isteyebiliriz veya alınan belge sayısını ayarlamak isteyebiliriz. Peki, **bu parametreleri kullanıcı sorgusuna göre nasıl dinamik olarak ayarlayabiliriz?**\n",
    "\n",
    "- RAG'de sık karşılaşılan bir sorun, kullanıcı sorgusuna verilen cevabın hangi belgeden geldiğinin bulunmamasıdır. **Eğer önceki sonuçlar alakalı değilse, retriever'ı değiştirilmiş bir sorgu ile tekrar çalıştırarak sonuç alma şansımız var mı?**\n",
    "\n",
    "\n",
    "🔧 Yukarıdaki noktaları basit bir şekilde çözebiliriz: **ajanımıza retriever'ın parametrelerinin kontrolünü vereceğiz!**\n",
    "\n",
    "➡️ Hadi bunu nasıl yapacağımızı gösterelim. İlk olarak üzerinde RAG uygulamak istediğimiz bir bilgi tabanını yüklüyoruz: bu veri seti, markdown olarak depolanan birçok Hugging Face kütüphanesinin dokümantasyon sayfalarının bir derlemesidir.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import datasets\n",
    "\n",
    "knowledge_base = datasets.load_dataset(\"m-ric/huggingface_doc\", split=\"train\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Şimdi veri setini işleyerek ve retriever tarafından kullanılacak bir vektör veritabanına depolayarak bilgi tabanını hazırlıyoruz. Vektör veritabanları için mükemmel yardımcı programlara sahip olduğu için LangChain'i kullanacağız:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/6m/9b1tts6d5w960j80wbw9tx3m0000gn/T/ipykernel_16932/1458839689.py:15: LangChainDeprecationWarning: The class `HuggingFaceEmbeddings` was deprecated in LangChain 0.2.2 and will be removed in 1.0. An updated version of the class exists in the :class:`~langchain-huggingface package and should be used instead. To use it run `pip install -U :class:`~langchain-huggingface` and import as `from :class:`~langchain_huggingface import HuggingFaceEmbeddings``.\n",
      "  embedding_model = HuggingFaceEmbeddings(model_name=\"thenlper/gte-small\")\n"
     ]
    }
   ],
   "source": [
    "from langchain.docstore.document import Document\n",
    "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
    "from langchain.vectorstores import FAISS\n",
    "from langchain_community.embeddings import HuggingFaceEmbeddings\n",
    "\n",
    "source_docs = [\n",
    "    Document(page_content=doc[\"text\"], metadata={\"source\": doc[\"source\"].split(\"/\")[1]})\n",
    "    for doc in knowledge_base\n",
    "]\n",
    "\n",
    "docs_processed = RecursiveCharacterTextSplitter(chunk_size=500).split_documents(\n",
    "    source_docs\n",
    ")[:1000]\n",
    "\n",
    "embedding_model = HuggingFaceEmbeddings(model_name=\"thenlper/gte-small\")\n",
    "vectordb = FAISS.from_documents(documents=docs_processed, embedding=embedding_model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Artık veritabanımız hazır olduğuna göre, kullanıcı sorgularını buna göre yanıtlayan bir RAG sistemi oluşturalım!\n",
    "\n",
    "Sistemimizin sorguya bağlı olarak yalnızca en alakalı bilgi kaynaklarından seçim yapmasını istiyoruz.\n",
    "\n",
    "Dökümantasyon sayfalarımız aşağıdaki kaynaklardan gelecek:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['datasets-server', 'datasets', 'optimum', 'gradio', 'blog', 'course', 'hub-docs', 'pytorch-image-models', 'peft', 'evaluate', 'diffusers', 'hf-endpoints-documentation', 'deep-rl-class', 'transformers']\n"
     ]
    }
   ],
   "source": [
    "all_sources = list(set([doc.metadata[\"source\"] for doc in docs_processed]))\n",
    "print(all_sources)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "👉 Şimdi ajanlarımızın bilgi tabanından bilgi almak için kullanabileceği bir `RetrieverTool` oluşturalım.\n",
    "\n",
    "Vectordb'yi aracın bir özelliği olarak eklememiz gerektiği için, [basit araç oluşturusunu](https://huggingface.co/docs/transformers/main/en/agents#create-a-new-tool) ve `@tool` dekoratörünü kullanmak yeterli olmayacak. Bu nedenle, [gelişmiş ajanlar dökümantasyonunda](https://huggingface.co/docs/transformers/main/en/agents_advanced#directly-define-a-tool-by-subclassing-tool-and-share-it-to-the-hub)  belirtilen gelişmiş yapılandırmayı takip edeceğiz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "from transformers.agents import Tool\n",
    "from langchain_core.vectorstores import VectorStore\n",
    "\n",
    "\n",
    "class RetrieverTool(Tool):\n",
    "    name = \"retriever\"\n",
    "    description = \"Retrieves some documents from the knowledge base that have the closest embeddings to the input query.\"\n",
    "    inputs = {\n",
    "        \"query\": {\n",
    "            \"type\": \"string\",\n",
    "            \"description\": \"The query to perform. This should be semantically close to your target documents. Use the affirmative form rather than a question.\",\n",
    "        },\n",
    "        \"source\": {\"type\": \"string\", \"description\": \"\"},\n",
    "        \"number_of_documents\": {\n",
    "            \"type\": \"string\",\n",
    "            \"description\": \"the number of documents to retrieve. Stay under 10 to avoid drowning in docs\",\n",
    "        },\n",
    "    }\n",
    "    output_type = \"string\"\n",
    "\n",
    "    def __init__(self, vectordb: VectorStore, all_sources: str, **kwargs):\n",
    "        super().__init__(**kwargs)\n",
    "        self.vectordb = vectordb\n",
    "        self.inputs[\"source\"][\"description\"] = (\n",
    "            f\"The source of the documents to search, as a str representation of a list. Possible values in the list are: {all_sources}. If this argument is not provided, all sources will be searched.\".replace(\n",
    "                \"'\", \"`\"\n",
    "            )\n",
    "        )\n",
    "\n",
    "    def forward(self, query: str, source: str = None, number_of_documents=7) -> str:\n",
    "        assert isinstance(query, str), \"Your search query must be a string\"\n",
    "        number_of_documents = int(number_of_documents)\n",
    "\n",
    "        if source:\n",
    "            if isinstance(source, str) and \"[\" not in str(\n",
    "                source\n",
    "            ):  # eğer kaynak bir listeyi temsil etmiyorsa\n",
    "                source = [source]\n",
    "            source = json.loads(str(source).replace(\"'\", '\"'))\n",
    "\n",
    "        docs = self.vectordb.similarity_search(\n",
    "            query,\n",
    "            filter=({\"source\": source} if source else None),\n",
    "            k=number_of_documents,\n",
    "        )\n",
    "\n",
    "        if len(docs) == 0:\n",
    "            return \"No documents found with this filtering. Try removing the source filter.\"\n",
    "        return \"Retrieved documents:\\n\\n\" + \"\\n===Document===\\n\".join(\n",
    "            [doc.page_content for doc in docs]\n",
    "        )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Opsiyonel: Retriever aracınızı Hub'da paylaşın\n",
    "\n",
    "Aracınızı Hub'da paylaşmak için, önce RetrieverTool tanım hücresindeki kodu kopyalayıp, örneğin `retriever.py` gibi bir adla yeni bir dosyaya yapıştırın.\n",
    "\n",
    "Araç ayrı bir dosyadan yüklendiğinde, aşağıdaki kodu kullanarak Hub'a gönderebilirsiniz (`yazma` yetkisine sahip bir token ile giriş yaptığınızdan emin olun)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "share_to_hub = True\n",
    "\n",
    "if share_to_hub:\n",
    "    from huggingface_hub import login\n",
    "    from retriever import RetrieverTool\n",
    "\n",
    "    login(\"your_token\")\n",
    "\n",
    "    tool = RetrieverTool(vectordb, all_sources)\n",
    "\n",
    "    tool.push_to_hub(repo_id=\"m-ric/retriever-tool\")\n",
    "\n",
    "    # Aracın Yüklenmesi\n",
    "    from transformers.agents import load_tool\n",
    "\n",
    "    retriever_tool = load_tool(\n",
    "        \"m-ric/retriever-tool\", vectordb=vectordb, all_sources=all_sources\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ajanı çalıştırın!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from transformers.agents import HfApiEngine, ReactJsonAgent\n",
    "\n",
    "llm_engine = HfApiEngine(\"Qwen/Qwen2.5-72B-Instruct\")\n",
    "\n",
    "retriever_tool = RetrieverTool(vectordb=vectordb, all_sources=all_sources)\n",
    "agent = ReactJsonAgent(tools=[retriever_tool], llm_engine=llm_engine, verbose=0)\n",
    "\n",
    "agent_output = agent.run(\"Please show me a LORA finetuning script\")\n",
    "\n",
    "print(\"Final output:\")\n",
    "print(agent_output)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Peki burada ne oldu? İlk olarak, ajan belirli kaynaklarla (`['transformers', 'blog']`) birlikte retriever'ı başlattı.\n",
    "\n",
    "Ancak bu arama yeterli sonucu vermedi. Sorun değil! Ajan, önceki sonuçlar üzerinde tekrar çalışabildiği için, daha az kısıtlayıcı arama parametreleriyle yeniden sorgulama yaptı ve sonuç olarak araştırma başarılı oldu!\n",
    "\n",
    "Bir LLM ajanının bir retriever aracını kullanarak dinamik olarak sorguyu ve retrieval parametrelerini değiştirebilmesi, RAG'in daha genel bir formülasyonunu oluşturur ve aynı zamanda yinelemeli sorgu iyileştirme gibi birçok RAG geliştirme tekniğini de kapsar.\n",
    "\n",
    "**Bir retriever'ı araç olarak kullanıp, sorguyu ve diğer** veri çekme parametrelerini dinamik olarak değiştirebilen **bir LLM ajanı kullanmak**, yinelemeli sorgu iyileştirmesi gibi birçok RAG geliştirme tekniğini de kapsayan **RAG'in daha genel bir formülasyonudur**.\n",
    "\n",
    "## 3. 💻 Python Kodunda Hata Ayıklama\n",
    "ReactCodeAgent'in yerleşik bir Python kod yorumlayıcısı olduğundan, hatalı Python scriptimizi debug etmek için kullanabiliriz!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001b[32;20;1m======== New task ========\u001b[0m\n",
      "\u001b[37;1mI have some code that creates a bug: please debug it, then run it to make sure it works and return the final code\n",
      "You have been provided with these initial arguments: {'code': '\\nlist=[0, 1, 2]\\n\\nfor i in range(4):\\n    print(list(i))\\n'}.\u001b[0m\n",
      "\u001b[33;1m=== Agent thoughts:\u001b[0m\n",
      "\u001b[0mThought: The provided code has a bug. The `list` is a built-in type in Python and should not be used as a variable name. Furthermore, the `list` type does not have a `__call__` method, which means that you cannot use parentheses to access its elements. Instead, square brackets should be used to index the list. I will correct the variable name and the indexing syntax and then run the code to ensure it works.\u001b[0m\n",
      "\u001b[33;1m>>> Agent is executing the code below:\u001b[0m\n",
      "\u001b[0m\u001b[38;5;7mmy_list\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01m=\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;7m[\u001b[39m\u001b[38;5;139m0\u001b[39m\u001b[38;5;7m,\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;139m1\u001b[39m\u001b[38;5;7m,\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;139m2\u001b[39m\u001b[38;5;7m]\u001b[39m\n",
      "\n",
      "\u001b[38;5;109;01mfor\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;7mi\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01min\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;109mrange\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;139m4\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[38;5;7m:\u001b[39m\n",
      "\u001b[38;5;7m    \u001b[39m\u001b[38;5;109;01mif\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;7mi\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01m<\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;109mlen\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7mmy_list\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[38;5;7m:\u001b[39m\n",
      "\u001b[38;5;7m        \u001b[39m\u001b[38;5;109mprint\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7mmy_list\u001b[39m\u001b[38;5;7m[\u001b[39m\u001b[38;5;7mi\u001b[39m\u001b[38;5;7m]\u001b[39m\u001b[38;5;7m)\u001b[39m\n",
      "\u001b[38;5;7m    \u001b[39m\u001b[38;5;109;01melse\u001b[39;00m\u001b[38;5;7m:\u001b[39m\n",
      "\u001b[38;5;7m        \u001b[39m\u001b[38;5;109mprint\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;144m\"\u001b[39m\u001b[38;5;144mIndex out of range\u001b[39m\u001b[38;5;144m\"\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[0m\n",
      "\u001b[33;1m====\u001b[0m\n",
      "\u001b[33;1mPrint outputs:\u001b[0m\n",
      "\u001b[32;20m0\n",
      "1\n",
      "2\n",
      "Index out of range\n",
      "\u001b[0m\n",
      "\u001b[33;1m=== Agent thoughts:\u001b[0m\n",
      "\u001b[0mThought: The code has been corrected and is running as expected, printing the list items for valid indices and an out-of-range message for invalid indices. I will return the final corrected code as the answer.\u001b[0m\n",
      "\u001b[33;1m>>> Agent is executing the code below:\u001b[0m\n",
      "\u001b[0m\u001b[38;5;7mfinal_answer\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7manswer\u001b[39m\u001b[38;5;109;01m=\u001b[39;00m\u001b[38;5;144m'''\u001b[39m\u001b[38;5;144mmy_list = [0, 1, 2]\u001b[39m\n",
      "\n",
      "\u001b[38;5;144mfor i in range(4):\u001b[39m\n",
      "\u001b[38;5;144m    if i < len(my_list):\u001b[39m\n",
      "\u001b[38;5;144m        print(my_list[i])\u001b[39m\n",
      "\u001b[38;5;144m    else:\u001b[39m\n",
      "\u001b[38;5;144m        print(\u001b[39m\u001b[38;5;144m\"\u001b[39m\u001b[38;5;144mIndex out of range\u001b[39m\u001b[38;5;144m\"\u001b[39m\u001b[38;5;144m)\u001b[39m\u001b[38;5;144m'''\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[0m\n",
      "\u001b[33;1m====\u001b[0m\n",
      "\u001b[33;1mPrint outputs:\u001b[0m\n",
      "\u001b[32;20m\u001b[0m\n",
      "\u001b[33;1mLast output from code snippet:\u001b[0m\n",
      "\u001b[32;20mmy_list = [0, 1, 2]\n",
      "\n",
      "for i in range(4):\n",
      "    if i < len(my_list):\n",
      "        print(my_list[i])\n",
      "    else:\n",
      "        print(\"Index out of range\")\u001b[0m\n",
      "\u001b[32;20;1mFinal answer:\u001b[0m\n",
      "\u001b[32;20mmy_list = [0, 1, 2]\n",
      "\n",
      "for i in range(4):\n",
      "    if i < len(my_list):\n",
      "        print(my_list[i])\n",
      "    else:\n",
      "        print(\"Index out of range\")\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "from transformers import ReactCodeAgent\n",
    "\n",
    "agent = ReactCodeAgent(tools=[], llm_engine=HfApiEngine(\"Qwen/Qwen2.5-72B-Instruct\"))\n",
    "\n",
    "code = \"\"\"\n",
    "list=[0, 1, 2]\n",
    "\n",
    "for i in range(4):\n",
    "    print(list(i))\n",
    "\"\"\"\n",
    "\n",
    "final_answer = agent.run(\n",
    "    \"I have some code that creates a bug: please debug it, then run it to make sure it works and return the final code\",\n",
    "    code=code,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Gördüğünüz gibi, ajan verilen kodu deniyor, bir hata alıyor, hatayı analiz ediyor, kodu düzeltiyor ve çalıştığını gördükten sonra geri veriyor!\n",
    "\n",
    "Sonuç olarak düzeltilen kodun son hali:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "my_list = [0, 1, 2]\n",
      "\n",
      "for i in range(4):\n",
      "    if i < len(my_list):\n",
      "        print(my_list[i])\n",
      "    else:\n",
      "        print(\"Index out of range\")\n"
     ]
    }
   ],
   "source": [
    "print(final_answer)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Kendi LLM motorunuzu oluşturun (OpenAI)\n",
    "\n",
    "Kendi LLM motorunuzu oluşturmak gerçekten çok kolay:\n",
    "sadece bu kriterlere sahip bir `__call__` yöntemine ihtiyaç duyar:\n",
    "1. Girdi olarak [ChatML formatında](https://huggingface.co/docs/transformers/main/en/chat_templating#introduction) bir mesaj listesi alır ve cevabı çıktı olarak verir.\n",
    "2. `stop_sequences` argümanını destekleyerek metin üretmeyi durduracak dizileri tanımlar.\n",
    "3. LLM'inizin desteklediği mesaj rolü (asistan, kullanıcı vb.) türlerine göre bazı mesaj rollerini dönüştürmeniz gerekebilir."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001b[33;1m======== New task ========\u001b[0m\n",
      "\u001b[37;1mI have some code that creates a bug: please debug it and return the final code\n",
      "You have been provided with these initial arguments: {'code': '\\nlist=[0, 1, 2]\\n\\nfor i in range(4):\\n    print(list(i))\\n'}.\u001b[0m\n",
      "\u001b[33;1m==== Agent is executing the code below:\u001b[0m\n",
      "\u001b[0m\u001b[38;5;7mmy_list\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01m=\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;7m[\u001b[39m\u001b[38;5;139m0\u001b[39m\u001b[38;5;7m,\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;139m1\u001b[39m\u001b[38;5;7m,\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;139m2\u001b[39m\u001b[38;5;7m]\u001b[39m\u001b[38;5;7m  \u001b[39m\u001b[38;5;60;03m# Renamed the list to avoid using the built-in name\u001b[39;00m\n",
      "\n",
      "\u001b[38;5;109;01mfor\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;7mi\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01min\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;109mrange\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;109mlen\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7mmy_list\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[38;5;7m:\u001b[39m\u001b[38;5;7m  \u001b[39m\u001b[38;5;60;03m# Changed the range to be within the length of the list\u001b[39;00m\n",
      "\u001b[38;5;7m    \u001b[39m\u001b[38;5;109mprint\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7mmy_list\u001b[39m\u001b[38;5;7m[\u001b[39m\u001b[38;5;7mi\u001b[39m\u001b[38;5;7m]\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[38;5;7m  \u001b[39m\u001b[38;5;60;03m# Corrected the list access syntax\u001b[39;00m\u001b[0m\n",
      "\u001b[33;1m====\u001b[0m\n",
      "\u001b[33;1mPrint outputs:\u001b[0m\n",
      "\u001b[32;20m0\n",
      "1\n",
      "2\n",
      "\u001b[0m\n",
      "\u001b[33;1m==== Agent is executing the code below:\u001b[0m\n",
      "\u001b[0m\u001b[38;5;7mmy_list\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01m=\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;7m[\u001b[39m\u001b[38;5;139m0\u001b[39m\u001b[38;5;7m,\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;139m1\u001b[39m\u001b[38;5;7m,\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;139m2\u001b[39m\u001b[38;5;7m]\u001b[39m\u001b[38;5;7m  \u001b[39m\u001b[38;5;60;03m# Renamed the list to avoid using the built-in name\u001b[39;00m\n",
      "\n",
      "\u001b[38;5;109;01mfor\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;7mi\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01min\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;109mrange\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;109mlen\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7mmy_list\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[38;5;7m:\u001b[39m\u001b[38;5;7m  \u001b[39m\u001b[38;5;60;03m# Changed the range to be within the length of the list\u001b[39;00m\n",
      "\u001b[38;5;7m    \u001b[39m\u001b[38;5;109mprint\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7mmy_list\u001b[39m\u001b[38;5;7m[\u001b[39m\u001b[38;5;7mi\u001b[39m\u001b[38;5;7m]\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[38;5;7m  \u001b[39m\u001b[38;5;60;03m# Corrected the list access syntax\u001b[39;00m\u001b[0m\n",
      "\u001b[33;1m====\u001b[0m\n",
      "\u001b[33;1mPrint outputs:\u001b[0m\n",
      "\u001b[32;20m0\n",
      "1\n",
      "2\n",
      "\u001b[0m\n",
      "\u001b[33;1m==== Agent is executing the code below:\u001b[0m\n",
      "\u001b[0m\u001b[38;5;7mcorrected_code\u001b[39m\u001b[38;5;7m \u001b[39m\u001b[38;5;109;01m=\u001b[39;00m\u001b[38;5;7m \u001b[39m\u001b[38;5;144m'''\u001b[39m\n",
      "\u001b[38;5;144mmy_list = [0, 1, 2]  # Renamed the list to avoid using the built-in name\u001b[39m\n",
      "\n",
      "\u001b[38;5;144mfor i in range(len(my_list)):  # Changed the range to be within the length of the list\u001b[39m\n",
      "\u001b[38;5;144m    print(my_list[i])  # Corrected the list access syntax\u001b[39m\n",
      "\u001b[38;5;144m'''\u001b[39m\n",
      "\n",
      "\u001b[38;5;7mfinal_answer\u001b[39m\u001b[38;5;7m(\u001b[39m\u001b[38;5;7manswer\u001b[39m\u001b[38;5;109;01m=\u001b[39;00m\u001b[38;5;7mcorrected_code\u001b[39m\u001b[38;5;7m)\u001b[39m\u001b[0m\n",
      "\u001b[33;1m====\u001b[0m\n",
      "\u001b[33;1mPrint outputs:\u001b[0m\n",
      "\u001b[32;20m\u001b[0m\n",
      "\u001b[33;1m>>> Final answer:\u001b[0m\n",
      "\u001b[32;20m\n",
      "my_list = [0, 1, 2]  # Renamed the list to avoid using the built-in name\n",
      "\n",
      "for i in range(len(my_list)):  # Changed the range to be within the length of the list\n",
      "    print(my_list[i])  # Corrected the list access syntax\n",
      "\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from openai import OpenAI\n",
    "from transformers.agents.llm_engine import MessageRole, get_clean_message_list\n",
    "\n",
    "openai_role_conversions = {\n",
    "    MessageRole.TOOL_RESPONSE: \"user\",\n",
    "}\n",
    "\n",
    "\n",
    "class OpenAIEngine:\n",
    "    def __init__(self, model_name=\"gpt-4o-2024-05-13\"):\n",
    "        self.model_name = model_name\n",
    "        self.client = OpenAI(\n",
    "            api_key=os.getenv(\"OPENAI_API_KEY\"),\n",
    "        )\n",
    "\n",
    "    def __call__(self, messages, stop_sequences=[]):\n",
    "        # Güvenli mesaj listesini edinin\n",
    "        messages = get_clean_message_list(\n",
    "            messages, role_conversions=openai_role_conversions\n",
    "        )\n",
    "\n",
    "        # LLM çıktısını alın\n",
    "        response = self.client.chat.completions.create(\n",
    "            model=self.model_name,\n",
    "            messages=messages,\n",
    "            stop=stop_sequences,\n",
    "        )\n",
    "        return response.choices[0].message.content\n",
    "\n",
    "\n",
    "openai_engine = OpenAIEngine()\n",
    "agent = ReactCodeAgent(llm_engine=openai_engine, tools=[])\n",
    "\n",
    "code = \"\"\"\n",
    "list=[0, 1, 2]\n",
    "\n",
    "for i in range(4):\n",
    "    print(list(i))\n",
    "\"\"\"\n",
    "\n",
    "final_answer = agent.run(\n",
    "    \"I have some code that creates a bug: please debug it and return the final code\",\n",
    "    code=code,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "my_list = [0, 1, 2]  # Renamed the list to avoid using the built-in name\n",
      "\n",
      "for i in range(len(my_list)):  # Changed the range to be within the length of the list\n",
      "    print(my_list[i])  # Corrected the list access syntax\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(final_answer)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ➡️ Son olarak\n",
    "\n",
    "Yukarıdaki kullanım örnekleri, Agents'ın sunduğu olanaklar hakkında size bir fikir verecektir.\n",
    "\n",
    "Daha gelişmiş kullanım için [dökümantasyonu](https://huggingface.co/docs/transformers/en/transformers_agents) ve Llama-3-70B'yi temel alan ve son derece zorlayıcı GAIA Liderlik Tablosunda birçok GPT-4 ajanlarını geride bırakan kendi ajanımızı oluşturmamızı sağlayan [bu deneyi](https://github.com/aymeric-roucher/agent_reasoning_benchmark/blob/main/benchmark_gaia.ipynb) okuyun!\n",
    "\n",
    "Tüm geri bildirimleri bekliyoruz, Agents'ı geliştirmemize yardımcı olacak!"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
